﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using UtilZ.Dotnet.Ex.Model;

namespace UtilZ.Dotnet.Ex.Communication.Ports
{
    /// <summary>
    /// 串口接口
    /// </summary>
    public interface ISerialPort : IDisposable
    {
        /// <summary>
        /// 原始串口对象
        /// </summary>
        object OriginSerialPort { get; }

        /// <summary>
        /// 指示串口对象打开或关闭状态
        /// </summary>
        bool IsOpen { get; }

        /// <summary>
        /// 获取接收缓冲区中数据字节数
        /// </summary>
        int BytesToRead { get; }

        /// <summary>
        /// 从输入缓冲区读取一些字节,并将读取到的字节写入字节数组指定的偏移量处
        /// </summary>
        /// <param name="buffer">将输入写入到其中的字节数据</param>
        /// <param name="offset">要写入字节buffer中偏移量</param>
        /// <param name="count">最多读取的字节数,如果count大于输入缓冲区中的字节数,则读取较少的字节</param>
        /// <returns>读取的字节数</returns>
        int Read(byte[] buffer, int offset, int count);

        /// <summary>
        /// 将指定的字符串写入串行端口
        /// 异常:
        /// T:System.InvalidOperationException:指定的端口未打开。
        /// T:System.ServiceProcess.TimeoutException:该操作未在超时时间到期之前完成。
        /// </summary>
        /// <param name="text">输出字符串</param>
        void Send(string text);

        /// <summary>
        /// 使用缓冲区的数据将指定数量的字节写入串行端口
        /// 异常:
        /// T:System.InvalidOperationException:指定的端口未打开。
        /// T:System.ArgumentOutOfRangeException:offset 或 count 参数超出了所传递的 buffer 的有效区域。offset 或 count 小于零。
        /// T:System.ArgumentException:offset 加上 count 大于 buffer 的长度。
        /// T:System.ServiceProcess.TimeoutException:该操作未在超时时间到期之前完成。
        /// </summary>
        /// <param name="buffer">包含要写入端口的数据的字节数组</param>
        /// <param name="offset">buffer 参数中从零开始的字节偏移量，从此处开始将字节复制到端口</param>
        /// <param name="size">要写入的字节数</param>
        void Send(byte[] buffer, int offset, int size);

        /// <summary>
        /// 使用缓冲区的数据将指定数量的字符写入串行端口
        /// 异常:
        /// T:System.InvalidOperationException:指定的端口未打开。
        /// T:System.ArgumentOutOfRangeException: offset 或 count 参数超出了所传递的 buffer 的有效区域。offset 或 count 小于零。
        /// T:System.ArgumentException:offset 加上 count 大于 buffer 的长度。
        /// T:System.ServiceProcess.TimeoutException:该操作未在超时时间到期之前完成。
        /// </summary>
        /// <param name="buffer">包含要写入端口的数据的字符数组</param>
        /// <param name="offset">buffer 参数中从零开始的字节偏移量，从此处开始将字节复制到端口</param>
        /// <param name="size">要写入的字符数</param>
        void Send(char[] buffer, int offset, int size);

        /// <summary>
        /// 将指定的字符串和 System.IO.Ports.SerialPort.NewLine 值写入输出缓冲区
        /// 异常:
        /// T:System.InvalidOperationException:指定的端口未打开。
        /// T:System.TimeoutException:System.IO.Ports.SerialPort.WriteLine(System.String) 方法未能写入流。
        /// </summary>
        /// <param name="text">写入输出缓冲区的字符串</param>
        void SendLine(string text);

        /// <summary>
        /// 打开一个新的串行端口连接
        /// </summary>
        void Open();

        /// <summary>
        /// 关闭串口连接,将IsOpen设置为false,并释放内部资源
        /// </summary>
        void Close();

        /// <summary>
        /// 串口上发生了错误事件
        /// </summary>
        [MonitoringDescription("SerialErrorReceived")]
        event EventHandler<EventArgs<SerialPortError>> ErrorReceived;

        /// <summary>
        /// 串口上发生了非数据信号事件
        /// </summary>
        [MonitoringDescription("SerialPinChanged")]
        event EventHandler<EventArgs<SerialPortPinChange>> PinChanged;

        /// <summary>
        /// 指示串口已接收到数据事件
        /// </summary>
        [MonitoringDescription("SerialDataReceived")]
        event EventHandler<EventArgs<SerialPortData>> DataReceived;
    }
}
